from  rest_framework.serializers import ModelSerializer
from apps.goods.models import SKU,SPU,SPUSpecification,SpecificationOption,SKUSpecification
from rest_framework.pagination import PageNumberPagination
from collections import OrderedDict
from rest_framework.response import Response
from apps.goods.models import GoodsCategory
from rest_framework import serializers
from django.db import transaction
from rest_framework.exceptions import ValidationError

class SKUSpecificationModelSerializer(ModelSerializer):
    """SKU具体规格序列化器"""
    option_id=serializers.IntegerField()
    spec_id=serializers.IntegerField()

    class Meta:
        model=SKUSpecification
        fields=('option_id','spec_id')

class SKUModelSerializer(ModelSerializer):
    """SKU序列化器"""
    spu=serializers.StringRelatedField()
    category=serializers.StringRelatedField()

    spu_id=serializers.IntegerField()
    category_id=serializers.IntegerField()

    specs=SKUSpecificationModelSerializer(many=True)

    def create(self, validated_data):
        """重写序列化器添加方法，一次添加多个数据"""
        specs=validated_data.pop('specs')

        with transaction.atomic():
            t=transaction.savepoint()
            try:
                sku=SKU.objects.create(**validated_data)
                for item in specs:
                    SKUSpecification.objects.create(sku=sku,**item)
            except Exception:
                transaction.savepoint_rollback(t)
            else:
                transaction.savepoint_commit(t)

        return sku


    def update(self, instance, validated_data):
        """重写序列化器更新方法，一次更新多个数据"""
        specs = validated_data.pop('specs')

        with transaction.atomic():
            t=transaction.savepoint()
            try:
                super().update(instance,validated_data)
                for item in specs:
                    SKUSpecification.objects.filter(sku=instance,spec_id=item.get('spec_id')).update(option_id=item['option_id'])
            except Exception:
                transaction.savepoint_rollback(t)
                raise ValidationError('更新sku失败')
            else:
                transaction.savepoint_commit(t)

        return instance

    class Meta:
        model=SKU
        fields='__all__'


class SKUPageNumberPagination(PageNumberPagination):
    """SKU分页类"""
    page_size=5
    page_size_query_param='pagesize'
    max_page_size = 20


    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('count', self.page.paginator.count),
            ('lists', data),
            ('page',self.page.number),
            ('pages',self.page.paginator.num_pages),
            ('pagesize',self.page.paginator.per_page),
        ]))


class GoodsCategoryModelSerializer(ModelSerializer):
    """三级视图GoodsCategory序列化器"""

    class Meta:
        model=GoodsCategory
        fields=('id','name')


class GoodsSPUModelSerializer(ModelSerializer):
    """获取SPU表名称数据序列化器"""

    class Meta:
        model=SPU
        fields=('id','name')


class SpecificationOptionModelSerializer(ModelSerializer):
    """商品规格选项序列化器"""

    class Meta:
        model=SpecificationOption
        fields=('id','value')


class SPUSpecificationModelSerializer(ModelSerializer):
    """SKU具体规格序列化器"""
    options=SpecificationOptionModelSerializer(many=True)

    class Meta:
        model=SPUSpecification
        fields='__all__'


